package com.bz.common;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;

public class DateUtlis {
    public static String YYYY_MM_DDHH_MM_SS   = "yyyyMMddHHmmss";
    public static String YYYY                 = "yyyy";
    public static String YYYY_MM              = "yyyy-MM";
    public static String YYYY_MM_DD           = "yyyy-MM-dd";
    public static String YYYYMMDDHHMMSS       = "yyyyMMddHHmmss";
    public static String YYYYMM               = "yyyyMMdd";
    public static String YYYY_MM_DD_HH_MM_SS  = "yyyy-MM-dd HH:mm:ss";
    public static String YYYY_MM_DD_HH_MM     = "yyyy-MM-dd HH:mm";
    public static String YYYYMMDDHHMMSSSSSSSS = "yyyyMMddHHmmssSSSSSS";

    public static String dateToString(Date date, String format) {
        if (null != date) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.format(date);
        }
        return "";
    }

    public static Date stringToDate(String date, String format) {
        if (!StringUtils.isEmpty(date)) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            try {
                return sdf.parse(date);
            } catch (ParseException e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 计算两个时间相差多少个年
     * 
     * @param early
     * @param late
     * @return
     * @throws ParseException
     */
    public static double yearsBetween(Date start, Date end) throws ParseException {
        int sumdays = daysBetween(start, end);
        DecimalFormat df = new DecimalFormat("#.00");
        return Double.valueOf(df.format((float) sumdays / 365));
    }

    /**
     * 计算两个时间相差多少个天
     * 
     * @param early
     * @param late
     * @return
     * @throws ParseException
     */
    public static int daysBetween(Date start, Date end) throws ParseException {
        // 得到两个日期相差多少天
        return hoursBetween(start, end) / 24;
    }

    /**
     * 计算两个时间相差多少小时
     * 
     * @param early
     * @param late
     * @return
     * @throws ParseException
     */
    public static int hoursBetween(Date start, Date end) throws ParseException {
        // 得到两个日期相差多少小时
        return minutesBetween(start, end) / 60;
    }

    /**
     * 计算两个时间相差多少分
     * 
     * @param early
     * @param late
     * @return
     * @throws ParseException
     */
    public static int minutesBetween(Date start, Date end) throws ParseException {
        // 得到两个日期相差多少分
        return secondesBetween(start, end) / 60;
    }

    /**
     * 计算两个时间相差多少秒
     * 
     * @param early
     * @param late
     * @return
     * @throws ParseException
     */
    public static int secondesBetween(Date start, Date end) throws ParseException {
        Calendar startDate = Calendar.getInstance();
        startDate.setTime(start);
        Calendar endDate = Calendar.getInstance();
        endDate.setTime(end);

        // 设置时间为0时
        startDate.set(Calendar.HOUR_OF_DAY, 0);
        startDate.set(Calendar.MINUTE, 0);
        startDate.set(Calendar.SECOND, 0);
        endDate.set(Calendar.HOUR_OF_DAY, 0);
        endDate.set(Calendar.MINUTE, 0);
        endDate.set(Calendar.SECOND, 0);
        // 得到两个日期相差多少秒
        return ((int) (endDate.getTime().getTime() / 1000) - (int) (startDate.getTime().getTime() / 1000));
    }

    public static int betweenDays(Date start, Date end) {
        if (null == start) {
            return 0;
        }
        if (null == end) {
            end = new Date();
        }

        // 获取相差的天数
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(start);
        long timeInMillis1 = calendar.getTimeInMillis();
        calendar.setTime(end);
        long timeInMillis2 = calendar.getTimeInMillis();

        long betweenDays = (timeInMillis2 - timeInMillis1) / (1000L * 3600L * 24L);
        return (int) betweenDays;
    }

    public static Date dateAdd(Date date, String flg, int v) {
        Calendar cl = Calendar.getInstance();
        cl.setTime(date);
        if ("y".equals(flg)) {
            cl.add(Calendar.YEAR, v);
        } else if ("m".equals(flg)) {
            cl.add(Calendar.MONTH, v);
        } else if ("d".equals(flg)) {
            cl.add(Calendar.DAY_OF_MONTH, v);
        } else if ("w".equals(flg)) {
            cl.add(Calendar.WEEK_OF_MONTH, v);
        } else if ("min".equals(flg)) {
            cl.add(Calendar.MINUTE, v);
        } else if ("h".equals(flg)) {
            cl.add(Calendar.HOUR, v);
        } else if ("s".equals(flg)) {
            cl.add(Calendar.SECOND, v);
        }
        return cl.getTime();
    }

    /**
     * 获取周周一
     * 
     * @param date
     * @return
     */
    public static Date getFisrtDayOfWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) {
            day_of_week = 7;
        }
        c.add(Calendar.DATE, -day_of_week + 1);
        return c.getTime();
    }

    /**
     * 获取周周一
     * 
     * @param date
     * @return
     */
    public static Date getLastDayOfWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) {
            day_of_week = 7;
        }
        c.add(Calendar.DATE, -day_of_week + 7);
        return c.getTime();
    }

    /**
     * 获取某月第一天
     * 
     * @param date
     * @return
     */
    public static Date getFisrtDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        // 获取某月最小天数
        int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);

        // 设置日历中月份的最小天数
        cal.set(Calendar.DAY_OF_MONTH, firstDay);
        return cal.getTime();
    }

    /**
     * 获取某月最后一天
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        // 获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);

        // 设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        return cal.getTime();
    }

    /**
     * 获取某年第一天日期
     * 
     * @param year
     *            年份
     * @return Date
     */
    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 获取某年最后一天日期
     */
    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();
        return initLastDay(currYearLast);
    }

    public static Date initDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date initLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    public static int hours(Date start, Date end) throws ParseException {
        Calendar startDate = Calendar.getInstance();
        startDate.setTime(start);
        Calendar endDate = Calendar.getInstance();
        endDate.setTime(end);

        // 设置时间为0时
        startDate.set(Calendar.MINUTE, 0);
        startDate.set(Calendar.SECOND, 0);
        endDate.set(Calendar.MINUTE, 0);
        endDate.set(Calendar.SECOND, 0);

        int sec = ((int) (endDate.getTime().getTime() / 1000) - (int) (startDate.getTime().getTime() / 1000));
        int d = sec / 60 / 60;
        return d;
    }

    public static Date getDataDayMin(Date date) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        cld.set(Calendar.SECOND, 0);
        cld.set(Calendar.MINUTE, 0);
        cld.set(Calendar.HOUR_OF_DAY, 0);
        return cld.getTime();
    }

    public static Date getDataDayMax(Date date) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        cld.set(Calendar.SECOND, 59);
        cld.set(Calendar.MINUTE, 59);
        cld.set(Calendar.HOUR_OF_DAY, 23);
        return cld.getTime();
    }

    public static int getHour(Date date) {
        if (null == date) {
            return 0;
        }
        long t = System.currentTimeMillis() - date.getTime();
        return (int) (t / 1000 / 60 / 60);
    }

    public static Date getDataDaytime(Date date, int h, int m, int s) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        cld.set(Calendar.SECOND, s);
        cld.set(Calendar.MINUTE, m);
        cld.set(Calendar.HOUR_OF_DAY, h);
        return cld.getTime();
    }
}
